home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
pd mix ii
/
rot
/
snake
/
snake.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-20
|
9KB
|
331 lines
/*****************************************************************
** Snake.c - KABjorke 30 March 87 **
** © 1987, National Pixel Products **
** Released to the Public Domain for Non-Commercial Purposes. **
** A variant on the old "bouncing lines" program. **
** This version uses multiple vertices and Bezier splines. **
*****************************************************************/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <graphics/text.h>
#define MAXVERT 15
#define BGPEN 0
#define FGPEN 1
#define LOPEN 2
#define HIPEN 3
/* Event() return codes */
#define DUNNO -1
#define RESIZED 1
#define TRAIL (Trails.Flags&CHECKED)
#define POLYS (ShoPoly.Flags&CHECKED)
/****************************************************************/
/******* Built-Ins **********************************************/
/****************************************************************/
extern LONG GfxBase;
extern LONG IntuitionBase;
extern struct Window *OpenWindow();
extern struct IntuiMessage *GetMsg();
/****************************************************************/
/******* Local IntuiJunk ****************************************/
/****************************************************************/
struct Window *w;
struct RastPort *rp;
struct IntuiMessage *message;
USHORT class;
struct TextAttr ROMFont8 = {
"Topaz80",8,0,0 /* Define text font for our screen */
};
struct IntuiText SText[2] = {
{LOPEN,BGPEN,JAM1,CHECKWIDTH,0,&ROMFont8,"Trails",NULL},
{LOPEN,BGPEN,JAM1,CHECKWIDTH,0,&ROMFont8,"Poly", NULL}
};
struct MenuItem ShoPoly = {
NULL, /* NextItem */
0,9,(CHECKWIDTH+50), 9, /* Corner, Size */
ITEMTEXT|HIGHCOMP|ISDRAWN|ITEMENABLED|CHECKIT|MENUTOGGLE, /* Flags */
0L, /* MutualExclude */
(APTR)&SText[1], NULL, /* ItemFill, SelectFill */
'\0', /* Command */
NULL, NULL /* SubItem, NextSelect */
};
struct MenuItem Trails = {
&ShoPoly, /* NextItem */
0,0,(CHECKWIDTH+50), 9, /* Corner, Size */
ITEMTEXT|HIGHCOMP|ISDRAWN|ITEMENABLED|CHECKIT|MENUTOGGLE, /* Flags */
0L, /* MutualExclude */
(APTR)&SText[0], NULL, /* ItemFill, SelectFill */
'\0', /* Command */
NULL, NULL /* SubItem, NextSelect */
};
struct Menu Options = {
NULL, /* NextMenu */
0,0,(CHECKWIDTH+54),9, /* Corner, Size */
MIDRAWN|MENUENABLED, /* Flags */
"Snake", /* MenuName */
&Trails /* FirstItem */
};
/****************************************************************/
/******* Window *************************************************/
/****************************************************************/
struct NewWindow nw = {
100,50, /* Starting corner */
300,100, /* Width, Height */
LOPEN,HIPEN, /* DetailPen, BlockPen */
CLOSEWINDOW|NEWSIZE, /* IDCMPFlags (Don't need MENUPICK!) */
WINDOWDEPTH|ACTIVATE|WINDOWDRAG|WINDOWCLOSE|
SMART_REFRESH|WINDOWSIZING, /* Flags */
NULL, /* FirstGadget */
NULL, /* Pointer to checkmark */
"Snake", /* title */
NULL, /* Screen */
NULL, /* Bitmap */
50,50,640,400, /* Size limits */
WBENCHSCREEN /* Type */
};
/****************************************************************/
/******* Spline Vars ********************************************/
/****************************************************************/
float coeffs[4][MAXVERT];
float P[2][4], Pv[2][4], xlf, ylf;
SHORT xlim, ylim;
SHORT DispVerts[(2*MAXVERT)];
SHORT OldVerts[16][(2*MAXVERT)];
SHORT control[8], oldcont[16][8];
/****************************************************************/
/****** Function Typing *****************************************/
/****************************************************************/
extern VOID AmiSetup();
extern VOID SplineSetup();
extern VOID CalcSnake();
extern SHORT Event();
/****************************************************************/
/******* Execution Begins Here **********************************/
/****************************************************************/
VOID _main()
{
register UWORD i;
register BOOL k;
UWORD onward = 0;
UWORD SnakeColr = FGPEN;
UWORD PolyColr = HIPEN;
LONG Iterate = 0L;
AmiSetup();
SplineSetup();
xlim = w->Width - 3;
ylim = w->Height - 2;
xlf = (float)xlim;
ylf = (float)ylim;
for(i=0;i<4;++i) {
P[0][i] = (float)(rand() % (xlim-2) + 1); /* random start */
P[1][i] = (float)(rand() % (ylim-14) + 13);
Pv[0][i] = (float)(rand() % 10 + 1); /* and vector */
Pv[1][i] = (float)(rand() % 10 + 1);
}
class = NULL;
do {
CalcSnake();
if ((!TRAIL) && (onward)) {
SetAPen(rp,BGPEN); /* erase old */
onward = Iterate & 15;
Move(rp,OldVerts[onward][0],OldVerts[onward][1]);
PolyDraw(rp,MAXVERT,&OldVerts[onward][0]);
if (POLYS) {
Move(rp,oldcont[onward][0],oldcont[onward][1]);
PolyDraw(rp,4,&oldcont[onward][0]);
}
}
SetAPen(rp,SnakeColr); /* Draw new Curve */
Move(rp,DispVerts[0],DispVerts[1]);
PolyDraw(rp,MAXVERT,&DispVerts[0]);
if (POLYS) {
SetAPen(rp,PolyColr);
Move(rp,control[0],control[1]);
PolyDraw(rp,4,&control[0]);
}
if((rand() & 127) < 2) { /* new color */
PolyColr = SnakeColr;
if (++SnakeColr > 3) SnakeColr = 1;
}
onward = (10 + Iterate++) & 15;
for (i=0; i<(2*MAXVERT); ++i) /* old curve */
OldVerts[onward][i] = DispVerts[i];
for (i=0; i<8; ++i) /* old control points */
oldcont[onward][i] = control[i];
for(i=0;i<4;++i) { /* update control points */
P[0][i] += Pv[0][i]; /* new control points */
P[1][i] += Pv[1][i];
if(P[0][i] < 2.0) { /* clipping */
P[0][i] = 2.0; Pv[0][i] = -Pv[0][i];
} else if(P[0][i] > xlf) {
P[0][i] = xlf; Pv[0][i] = -Pv[0][i];
}
if(P[1][i] < 10.0) {
P[1][i] = 10.0; Pv[1][i] = -Pv[1][i];
} else if(P[1][i] > ylf) {
P[1][i] = ylf; Pv[1][i] = -Pv[1][i];
}
if(((rand() >> 5) & 127) < 2) { /* change x speed */
k = (Pv[0][i] < 0.0);
Pv[0][i] = (rand() >> 5) & 7;
if (k) Pv[0][i] = -Pv[0][i];
}
if(((rand() >> 5) & 255) < 50) { /* change y speed */
k = (Pv[1][i] < 0.0);
Pv[1][i] = (rand() >> 5) & 7;
if (k) Pv[1][i] = -Pv[1][i];
}
}
onward = 1;
if(w->UserPort->mp_SigBit) {
message = GetMsg(w->UserPort);
if(message != NULL) {
class = message->Class;
ReplyMsg(message);
}
}
} while(Event());
ClearMenuStrip(w);
CloseWindow(w);
CloseLibrary(IntuitionBase);
CloseLibrary(GfxBase);
}
/****************************************************************/
/****** Analyse IDCMP events ************************************/
/****************************************************************/
SHORT Event()
{
switch(class) {
case CLOSEWINDOW:
return(NULL);
break;
case NEWSIZE:
class = NULL;
xlim = w->Width - 3;
ylim = w->Height -2;
xlf = (float)xlim;
ylf = (float)ylim;
return(RESIZED);
break;
}
return(DUNNO);
}
/****************************************************************/
/****** Set up display & libraries ******************************/
/****************************************************************/
VOID AmiSetup()
{
if ((GfxBase = OpenLibrary("graphics.library",LIBRARY_VERSION))
== NULL) {
Exit(20);
}
if ((IntuitionBase = OpenLibrary("intuition.library",LIBRARY_VERSION))
== NULL) {
CloseLibrary(GfxBase);
Exit(20);
}
if ((w = OpenWindow(&nw)) == NULL) {
CloseLibrary(IntuitionBase);
CloseLibrary(GfxBase);
Exit(20);
}
rp = w->RPort;
SetAPen(rp,HIPEN);
SetDrMd(rp,JAM1);
SetMenuStrip(w,&Options);
}
/****************************************************************/
/******* Precalculate Spline Coefficients ***********************/
/****************************************************************/
VOID SplineSetup()
{
float t;
UWORD i;
for (i=0; i<MAXVERT; ++i) {
t = (float)i / (float)(MAXVERT-1);
coeffs[3][i] = 1.0 - t;
coeffs[2][i] = coeffs[3][i] * coeffs[3][i];
coeffs[0][i] = t * (coeffs[1][i] = t*t);
coeffs[1][i] *= (3.0 * coeffs[3][i]);
coeffs[3][i] *= coeffs[2][i];
coeffs[2][i] *= (3.0 * t);
}
}
/****************************************************************/
/****** Recalculate snake vertices ******************************/
/****************************************************************/
VOID CalcSnake()
{
register i, j;
float xt, yt;
short ndx;
ndx = 0;
for (i=0; i<MAXVERT; ++i) {
xt = yt = 0.0;
for (j=0; j<4; ++j) {
xt += P[0][j] * coeffs[j][i];
yt += P[1][j] * coeffs[j][i];
}
#ifdef DEBUG
/* clip is unnessesary because of bounding-poly adherence */
if (xt<2.0) xt = 2.0;
if (xt>xlim) xt = xlim;
if (yt<12.0) yt = 12.0;
if (yt>ylim) yt = ylim;
#endif DEBUG
DispVerts[ndx++] = (SHORT)xt;
DispVerts[ndx++] = (SHORT)yt;
}
ndx = 0;
for (i=0; i<4; ++i) {
control[ndx++] = (SHORT)P[0][i];
control[ndx++] = (SHORT)P[1][i];
}
}
/****************************************************************/
/******************************************************** eof ***/
/****************************************************************/